import * as Cesium from '@cesiumjs';
import {
  defaultViewerOptions,
  defaultViewerDefinition,
  EMPTY_OBJECT
} from "./defaults";
import {
  g3x_defineProperty,
  g3x_defineReadonly,
  GUID
} from "@g3x/utils";
import {viewerUtils, tilesetUtils, layersUtils, imageLayerUtils} from "../../viewerUtils";


function createImageProviderByOptions(czmOptions) {
  const imageryProvider = czmOptions.imageryProvider;
  if (imageryProvider instanceof Cesium.ImageryProvider) {
    return imageryProvider;
  }

  let imagery = czmOptions.imagery;
  if (!imagery) {
    console.warn("imagery is required!")
    return;
  }
  return imageLayerUtils.createImageProvider(imagery)
}

function createTerrainProviderByOptions(czmOptions) {
  const terrainProvider = czmOptions.terrainProvider;
  if (terrainProvider && terrainProvider instanceof Cesium.TerrainProvider) {
    return terrainProvider;
  }

  let terrain = czmOptions.terrain;
  if (!terrain) {
    console.warn("terrain is required!")
    return;
  }

  const {
    type,
    options
  } = terrain;
  if (type === "default") {
    return Cesium.createWorldTerrain(options)
  } else if (type === "ellipsoid") {
    return Cesium.EllipsoidTerrainProvider(options)
  } else if (type === "cesium") {
    return new Cesium.CesiumTerrainProvider({
      url: Cesium.IonResource.fromAssetId(3956),
      requestVertexNormals: true,
      ...options,
    })
  }

  return undefined
}

export function verifyViewerOptions(viewerOptions) {
  const {viewer} = viewerOptions
  viewerOptions.viewer = {
    ...defaultViewerOptions,
    ...viewer
  }
  if(!viewerOptions.name){
    viewerOptions.name = GUID.generate8();
  }
  viewerOptions.guid = GUID.generate32();
  if(!viewerOptions.title){
    viewerOptions.title = viewerOptions.name;
  }

  return viewerOptions
}

export function createViewer(container, viewerOptions) {
  if (!container) {
    console.error("container is required!")
    return;
  }

  const { viewer: options } = viewerOptions;

  options.imageryProvider = createImageProviderByOptions(options)
  options.terrainProvider = createTerrainProviderByOptions(options)

  const viewer = new Cesium.Viewer(container, options);

  g3x_defineProperty(viewer,"name", viewerOptions.name)
  g3x_defineProperty(viewer,"title", viewerOptions.title)

  return viewer
}
